package com.lushu.data
{
	import com.lushu.graphics.interfaces.ITileset;
	import com.lushu.helpers.io.GenericIO;
	import com.lushu.utils.CommonUtil;
	import com.lushu.utils.IList;
	
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Rectangle;
	
	public class TilesetInfo extends EventDispatcher implements IList, ITileset
	{
		private var name_ : String;
		private var nameId_ : String;
		
		private var ioUtil_ : GenericIO;
		
		private var tilesetImage_ : BitmapData;
		private var tilesetImageObject_ : TilesetImage
		
		private var tileSize_ : int;
		private var tilePerRow_ : int;
		private var cuttingRect_ : Rectangle;
		private var tileBitmap_ : BitmapData;
		private var tileWidth_ : int;
		private var tileHeight_ : int;
		
		private var id_ : int;
		
		// List related
		private var next_ : TilesetInfo;
		
		public function TilesetInfo(tilesetImage : TilesetImage, id : int)
		{
			tilesetImageObject_ = tilesetImage;
			tilesetImage_ = tilesetImage.getData();
			
			id_ = id;
			name_ = tilesetImage.getName();
			var nameArr : Array = name_.split(".");
			nameId_ = nameArr[0];
			
			tileWidth_ = tilesetImage_.width;
			tileHeight_ = tilesetImage_.height;
			
			tileSize_ = CommonUtil.TILE_SIZE;
			tilePerRow_ = int(Math.ceil(tileWidth_ / tileSize_));
			cuttingRect_ = new Rectangle(0, 0, tileSize_, tileSize_);
			tileBitmap_ = new BitmapData(tileSize_, tileSize_);
			dispatchEvent(new Event("tilesetLoaded"));	
		}
		
		public function get id() : int
		{
			return id_;
		}
		
		public function getTilesetImageObject() : TilesetImage
		{
			return tilesetImageObject_;
		}
		
		public function setTileSize(tileSize : int) : void
		{
			
		}
		
		public function getTileById(id : int) : BitmapData
		{
			cuttingRect_.x = (id  - tilePerRow_ * int(id / tilePerRow_)) * tileSize_;
			cuttingRect_.y = int(id / tilePerRow_) * tileSize_;
			cuttingRect_.width = tileSize_;
			cuttingRect_.height = tileSize_;
			
			tileBitmap_.fillRect(CommonUtil.BASE_RECT, 0);
			tileBitmap_.copyPixels(tilesetImage_, cuttingRect_, CommonUtil.BASE_POINT);
			
			return tileBitmap_;
		}
		
		public function getTile(tileX : int, tileY : int) : BitmapData
		{
			cuttingRect_.x = tileX * tileSize_;
			cuttingRect_.y = tileY * tileSize_;
			cuttingRect_.width = tileSize_;
			cuttingRect_.height = tileSize_;
			
			tileBitmap_.fillRect(cuttingRect_, 0);
			tileBitmap_.copyPixels(tilesetImage_, cuttingRect_, CommonUtil.BASE_POINT);
			
			return tileBitmap_;
		}
		
		public function getTileRect(pointRect : Rectangle) : BitmapData
		{
			cuttingRect_.x = pointRect.top * tileSize_;
			cuttingRect_.y = int(pointRect.left / tilePerRow_) * tileSize_;
			cuttingRect_.width = pointRect.right * tileSize_;
			cuttingRect_.height = int(pointRect.bottom / tilePerRow_) * tileSize_;
		
			var bit : BitmapData = new BitmapData(tileSize_ * (cuttingRect_.width - cuttingRect_.x), tileSize_ * (cuttingRect_.height - cuttingRect_.y));			
			bit.copyPixels(tilesetImage_, cuttingRect_, CommonUtil.BASE_POINT);
			
			return bit;
		}
		
		public function getData() : BitmapData
		{
			return tilesetImage_;
		}
		
		public function setNext(tileset : TilesetInfo) : void
		{
			next_ = tileset;
		}
		
		public function getNext() : IList
		{
			return next_;
		}
		
		public function getLast() : IList
		{
			if(next_ != null)
				return next_.getLast();
			else
				return this;
		}
		
		public function addLast(element : ITileset) : void
		{
			var last : TilesetInfo = getLast() as TilesetInfo;
			last.setNext(element as TilesetInfo);
		}
		
		public function removeListElement(listElement : IList) : IList
		{
			if(listElement == this)
			{
				return getNext();
			}
			else
			{
				setNext(getNext().removeListElement(listElement) as TilesetInfo);
				return this;
			}	
		}
		
		public function hasNext() : Boolean
		{
			return (next_ != null);
		}
		
		public function getByName(name : String) : ITileset
		{
			if(name != name_ && (name+".png") != name_)
			{
				if(hasNext())
					return (getNext() as TilesetInfo).getByName(name);
				else
					return null
			}
			else
				return this;
		}
		
		public function getByID(id : int) : ITileset
		{
			if(id != id_)
			{
				if(hasNext())
					return (getNext() as TilesetInfo).getByID(id);
				else
					return null
			}
			else
				return this;
		}
		
		public function getName() : String
		{
			return name_;
		}
		
		public function getNameId() : String
		{
			return nameId_;
		}
		public function getLength() : int
		{
			return int(tileWidth_ * tileHeight_) / (tileSize_ * tileSize_);
		}
		
		public function get label() : String
		{
			var name : Array = name_.split("/");
			return name[name.length-1];	
		}
		
		public function getWidth() : int
		{
			return tileWidth_;
		}
		
		public function getHeight() : int
		{
			return tileHeight_;
		}
	}
}